//最大m子段和问题，子段不交叉，可不连续
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN=1000050;
const int INF=100000007;
//原序列
int num[MAXN];
//d[i]表示前i个数分成m段的最大和
int d[MAXN];
//p[i-1]表示前i-1个数分成m-1段的最大和
int p[MAXN];
//状态转移方程：d[i]=max(d[i-1],p[i-1])+num[i]
//i位置的m段最大和分为两种情况，一是num[i]也归在前面这一子段里，那个d[i]就等于d[i-1]
//二是前面是m-1段最大和，而从num[i]开始新的一段,而p[i-1]就是记录前i-1个数分为m-1段的最大和
//取这两个情况的最大值
int main(void){
    int m,n;
    while(~scanf("%d%d",&m,&n)){
        int t;
		//初始化
        for(int i=1;i<=n;i++){
            scanf("%d",&num[i]);
        }
        memset(d,0,sizeof(d));
        memset(p,0,sizeof(p));

        for(int i=1;i<=m;i++){
            t=-1*INF;
            for(int j=i;j<=n;j++){
				//状态转移
                d[j]=max(d[j-1],p[j-1])+num[j];
				//用来记录p[i]
                p[j-1]=t;
                t=max(t,d[j]);
            }
        }
        printf("%d\n",t);
    }
    return 0;
}
